package com.weilx959.spt.core.utils;

import com.weilx959.spt.core.component.FormItemControl;
import com.weilx959.spt.core.exception.FormControlException;
import javafx.fxml.FXMLLoader;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.URL;
import java.util.Locale;
import java.util.ResourceBundle;

/**
 * FXML 工具类
 *
 * @author weilx
 * @since 2023-7-27
 */
@Slf4j
public class FXMLUtil {
    private FXMLUtil() {
    }

    public static <T> T getController(URL url) {
        return getController(null, url);
    }

    public static <T> T getController(String path) {
        return getController(Thread.currentThread().getContextClassLoader(), path);
    }

    public static <T> T getController(ClassLoader classLoader, String path) {
        return getController(classLoader.getResource(path));
    }

    public static <T> T getController(Class<?> clazz, String path) {
        return getController(clazz.getResource(path));
    }

    public static <T> T getController(ResourceBundle resourceBundle, URL url) {
        try {
            final var loader = new FXMLLoader();
            loader.setResources(resourceBundle);
            loader.setLocation(url);
            loader.load();
            return loader.getController();
        } catch (IOException e) {
            log.error("load FXML failed", e);
            throw new IllegalStateException(e);
        }
    }

    public static <T> T getController(String path, ResourceBundle resourceBundle) {
        return getController(Thread.currentThread().getContextClassLoader(), path, resourceBundle);
    }

    public static <T> T getController(ClassLoader classLoader, String path, ResourceBundle resourceBundle) {
        return getController(resourceBundle, classLoader.getResource(path));
    }

    public static <T> T getController(Class<?> clazz, String path, ResourceBundle resourceBundle) {
        return getController(resourceBundle, clazz.getResource(path));
    }

    public static <T> T getController(URL url, String baseName, Locale locale) {
        return getController(ResourceBundle.getBundle(baseName, locale), url);
    }

    public static <T> T getController(String path, String baseName, Locale locale) {
        return getController(Thread.currentThread().getContextClassLoader(), path, ResourceBundle.getBundle(baseName, locale));
    }

    public static <T> T getController(Class<?> clazz, String path, String baseName, Locale locale) {
        return getController(ResourceBundle.getBundle(baseName, locale, clazz.getModule()), clazz.getResource(path));
    }

    public static void loadControl(FormItemControl<?> control, String path) {
        loadControl(control, path, null);
    }

    public static void loadControl(FormItemControl<?> control, String path, ResourceBundle resourceBundle) {
        // load
        FXMLLoader fxmlLoader = new FXMLLoader(control.getClass().getResource(path));
        fxmlLoader.setResources(resourceBundle);
        fxmlLoader.setRoot(control);
        fxmlLoader.setController(control);

        try {
            fxmlLoader.load();
        } catch (IOException e) {
            throw new FormControlException(e, control.getClass());
        }
    }

    public static void loadControl(FormItemControl<?> control, String path, String baseName, Locale locale) {
        loadControl(control, path, ResourceBundle.getBundle(baseName, locale, control.getClass().getModule()));
    }
}
